package com.flute.framework.util.ftp;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

public class FileOperationHandler implements InvocationHandler {

	private static String[] methodUrifirst = { "removeDirectory", "download",
			"exists", "isDirectory", "isFile", "list", "load", "mkdir", "save",
			"lastModified", "clearFolder", "getNotLockLastModifiedTime" };
	private static String[] methodOverloading = { "createNewFile", "delete" };
	private static String[] methodUriEnd = { "upload" };

	private FtpFile file;

	public FileOperationHandler(FtpFile file) {
		super();
		this.file = file;
	}

	private boolean in(String str, String[] group) {
		if (str == null) {
			return false;
		}
		if (group == null || group.length == 0) {
			return false;
		}
		for (String g : group) {
			if (str.equals(g)) {
				return true;
			}
		}
		return false;
	}

	private Object[] updateArgs(Object[] args, String uri, String methodName) {
		List<Object> objList = new ArrayList<Object>();
		for (Object a : args) {
			objList.add(a);
		}
		if (in(methodName, methodUrifirst)) {
			objList.remove(0);
			objList.add(0, uri);
		} else if (in(methodName, methodUriEnd)) {
			objList.remove(args.length - 1);
			objList.add(uri);
		} else if (in(methodName, methodOverloading)) {
			if (args.length == 1) {
				objList.remove(0);
				objList.add(0, uri);
			}
		} else {
			// do something
		}
		return objList.toArray(new String[objList.size()]);
	}

	private String[] parseUri(String uri) {
		if (uri == null)
			throw new NullPointerException();
		uri = uri.trim();
		uri = uri.startsWith("/") ? uri.substring(1) : uri;
		return uri.split("/");
	}

	private String getUri(String methodName, Object[] args) {
		String uri = null;
		if (in(methodName, methodUrifirst)) {
			uri = (String) args[0];
		} else if (in(methodName, methodUriEnd)) {
			uri = (String) args[args.length - 1];

		} else if (in(methodName, methodOverloading)) {
			if (args.length == 1) {
				uri = (String) args[0];
			}
		} else {
			// do something
		}
		return uri;
	}

	public IFileOperation getPorxyInstance(IFileOperation oper) {
		// 返回的是realConnection代理类,实际上是Connection的子类
		return (IFileOperation) Proxy.newProxyInstance(oper.getClass()
				.getClassLoader(), new Class[] { IFileOperation.class }, this);
	}
 
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		String methodName = method.getName();
		String uri = getUri(methodName, args);
		if (uri != null) {
			String[] paths = parseUri(uri);
			file.ftpServer.changeDirectory(paths, paths.length - 1);
			Object[] newArgs = updateArgs(args, paths[paths.length - 1],
					methodName);
			Object result = null;
			try {
				result = method.invoke(file, newArgs);
			} finally {
				file.ftpServer.back(paths.length - 1);
			}
			return result;
		} else {
			return method.invoke(file, args);
		}
	}

	public static void main(String[] args) {
		System.out.println("a/b/".split("/").length);
	}
}
